package com.foxchen.ddns.service.impl;

import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.auth.SignOptions;
import com.baidubce.http.HttpMethodName;
import com.baidubce.internal.InternalRequest;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.foxchen.ddns.config.BceConfig;
import com.foxchen.ddns.config.DDNSConfig;
import com.foxchen.ddns.core.BceV1Signer;
import com.foxchen.ddns.service.DomainUpdateDnsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URI;
import java.util.*;

@Slf4j
@Service("baidu")
public class BaiduBceUpdateServiceImpl extends DomainUpdateDnsServiceAbs implements DomainUpdateDnsService {
    /**
     * 获取百度解析记录
     */
    private static final String GET_OLD_ANALYSIS = "https://bcd.baidubce.com/v1/domain/resolve/list";
    /**
     * 修改解析记录
     */
    private static final String EDIT_ANALYSIS = "https://bcd.baidubce.com/v1/domain/resolve/edit";
    @Resource
    private BceConfig bceConfig;
    @Resource
    private IpGetService ipGetService;

    @Override
    @SuppressWarnings("all")
    public void updateDnsSafe(String domain, DDNSConfig.Detail detail) throws Exception {
        // 获取当前公网ip
        log.info(">>================ddns check and update begin================>>");
        ObjectMapper objectMapper = new ObjectMapper();
        String localPublicIp = ipGetService.getLocalPublicIp(detail);
        log.info("===============public ip:{}===============",localPublicIp);

        // 查询原有的解析记录
        HttpRequest request = HttpUtil.createPost(GET_OLD_ANALYSIS);
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("pageNo","1");
        paramMap.put("pageSize","100");
        paramMap.put("domain",domain);
        request.body(objectMapper.writeValueAsString(paramMap), ContentType.JSON.getValue());
        request.headerMap(buildSign(GET_OLD_ANALYSIS).getHeaders(),false);

        // 得到响应
        HttpResponse response = request.execute();
        log.info("ddns old info body={}",response.body());

        Map<String, Object> objectMap = new ObjectMapper().readValue(response.body(), new TypeReference<Map<String, Object>>() {});
        List<Map<String,Object>> result = (List<Map<String,Object>>)objectMap.get("result");

        // 如果没有记录与当前公网ip匹配 则修改某一条记录
        result
                .stream()
                .filter(map -> {
                    String recordType = "v4".equals(detail.getType()) ? "A" : "AAAA";
                    // A记录类型
                    return recordType.equals(map.get("rdtype")) &&
                            // 指定解析记录
                            detail.getAnalysis().contains(map.get("domain").toString()) &&
                            // 绑定主机与当前不一致的
                            !localPublicIp.equals(map.get("rdata"));
                })
                .forEach(needUpdate -> {
                    try{
                        log.info("old info ==> {},new ip ==> {}",needUpdate,localPublicIp);
                        needUpdate.put("rdata",localPublicIp);
                        needUpdate.put("rdType",needUpdate.get("rdtype"));
                        needUpdate.remove("status");

                        request.setUrl(EDIT_ANALYSIS);
                        request.body(objectMapper.writeValueAsString(needUpdate),ContentType.JSON.getValue());
                        request.headerMap(buildSign(EDIT_ANALYSIS).getHeaders(),true);
                        log.info("begin update request = {}",request);
                        HttpResponse execute = request.execute();
                        String responseStr = execute.body();
                        log.info("😄update success,😄response is={}",responseStr);
                    }
                    catch (Exception e){
                        log.error("update fail.needUpdate={}",needUpdate,e);
                    }
                });
        log.info("<<================ddns check and update end================<<");
    }

    private InternalRequest buildSign(String url){
        // 创建请求 加上参数
        InternalRequest internalRequest = new InternalRequest(HttpMethodName.POST, URI.create(url));

        // ac key,se key
        DefaultBceCredentials defaultBceCredentials = new DefaultBceCredentials(bceConfig.getAccessKey(), bceConfig.getSecretKey());

        // 校验域
        SignOptions signOptions = new SignOptions();
        Set<String> signHead = new HashSet<>();
        signHead.add("host");
        signOptions.setHeadersToSign(signHead);

        // 签名
        BceV1Signer signer = new BceV1Signer();
        signer.sign(internalRequest,defaultBceCredentials,signOptions);

        return internalRequest;
    }
}
